home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / frasrc19.zip / FRAMAIN2.C < prev    next >
Text File  |  1995-03-08  |  55KB  |  1,699 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #ifndef XFRACT
  6. #include <io.h>
  7. #include <dos.h>
  8. #include <stdarg.h>
  9. #else
  10. #include <varargs.h>
  11. #endif
  12. #include <ctype.h>
  13. #include "prototyp.h"
  14. #include "fractype.h"
  15. #include "helpdefs.h"
  16.  
  17. #if 0
  18. /* makes a handly list of jul-man pairs, not for release */
  19. static void julman()
  20. {
  21.    FILE *fp;
  22.    int i;
  23.    fp = dir_fopen(workdir,"toggle.txt","w");
  24.    i = -1;
  25.    while(fractalspecific[++i].name)
  26.    {
  27.       if(fractalspecific[i].tojulia != NOFRACTAL && fractalspecific[i].name[0] != '*')
  28.          fprintf(fp,"%s  %s\n",fractalspecific[i].name,
  29.              fractalspecific[fractalspecific[i].tojulia].name);  
  30.    }
  31.    fclose(fp);
  32. }
  33. #endif
  34.  
  35. /* routines in this module    */
  36.  
  37. int main_menu_switch(int*,int*,int*,char*,int);
  38. int big_while_loop(int *kbdmore, char *stacked, int resumeflag);
  39. static void move_zoombox(int);
  40. char fromtext_flag = 0;        /* = 1 if we're in graphics mode */
  41. static int call_line3d(BYTE *pixels, int linelen);
  42. static    void note_zoom(void);
  43. static    void restore_zoom(void);
  44. static    void move_zoombox(int keynum);
  45. static    void cmp_line_cleanup(void);
  46. static void _fastcall restore_history_info(int);
  47. static void _fastcall save_history_info(void);
  48.  
  49. static char far *savezoom;
  50. static  int       historyptr = -1;    /* user pointer into history tbl  */
  51. static  int       saveptr = 0;     /* save ptr into history tbl      */
  52. static  int       historyflag;     /* are we backing off in history? */
  53. void (*outln_cleanup) (void);
  54.  
  55. int big_while_loop(int *kbdmore, char *stacked, int resumeflag)
  56. {
  57.    int       frommandel;            /* if julia entered from mandel */
  58.    int       axmode=0, bxmode, cxmode, dxmode; /* video mode (BIOS ##)    */
  59.    double  ftemp;            /* fp temp            */
  60.    int       i;                /* temporary loop counters    */
  61.    int kbdchar;
  62.    frommandel = 0;
  63.    if(resumeflag)
  64.       goto resumeloop;
  65.     for(;;) {            /* eternal loop */
  66.       if (calc_status != 2 || showfile == 0) {
  67. #ifdef XFRACT
  68.          if (resizeWindow()) {
  69.          calc_status = -1;
  70.      }
  71. #endif
  72.      far_memcpy((char far *)&videoentry,(char far *)&videotable[adapter],
  73.             sizeof(videoentry));
  74.      axmode  = videoentry.videomodeax; /* video mode (BIOS call)   */
  75.      bxmode  = videoentry.videomodebx; /* video mode (BIOS call)   */
  76.      cxmode  = videoentry.videomodecx; /* video mode (BIOS call)   */
  77.      dxmode  = videoentry.videomodedx; /* video mode (BIOS call)   */
  78.      dotmode = videoentry.dotmode;       /* assembler dot read/write */
  79.      xdots     = videoentry.xdots;       /* # dots across the screen */
  80.      ydots     = videoentry.ydots;       /* # dots down the screen   */
  81.      colors  = videoentry.colors;       /* # colors available */
  82.      textsafe2 = dotmode / 100;
  83.      dotmode  %= 100;
  84.      sxdots  = xdots;
  85.      sydots  = ydots;
  86.      sxoffs = syoffs = 0;
  87.  
  88.      diskvideo = 0;         /* set diskvideo flag */
  89.      if (dotmode == 11)        /* default assumption is disk */
  90.         diskvideo = 2;
  91.  
  92.      memcpy(olddacbox,dacbox,256*3); /* save the DAC */
  93.      diskisactive = 1;        /* flag for disk-video routines */
  94.  
  95.      if (overlay3d) {
  96.         unstackscreen();        /* restore old graphics image */
  97.         overlay3d = 0;
  98.         }
  99.  
  100.      else {
  101.                setvideomode(axmode,bxmode,cxmode,dxmode); /* switch video modes */
  102.         if (goodmode == 0) {
  103.            static FCODE msg[] = {"That video mode is not available with your adapter."};
  104.            static FCODE TPlusStr[] = "This video mode requires 'noninterlaced=yes'";
  105.  
  106.            if(TPlusErr) {
  107.           stopmsg(0, TPlusStr);
  108.           TPlusErr = 0;
  109.           }
  110.            else {
  111.           stopmsg(0,msg);
  112.           askvideo = TRUE;
  113.           }
  114.            initmode = -1;
  115.            setvideotext(); /* switch to text mode */
  116.            /* goto restorestart; */
  117.            return(RESTORESTART);
  118.            }
  119.         }
  120.  
  121.      diskisactive = 0;        /* flag for disk-video routines */
  122.      if (savedac || colorpreloaded) {
  123.         memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
  124.         spindac(0,1);
  125.         colorpreloaded = 0;
  126.         }
  127.      else { /* reset DAC to defaults, which setvideomode has done for us */
  128.         if (mapdacbox) { /* but there's a map=, so load that */
  129.            far_memcpy((char far *)dacbox,mapdacbox,768);
  130.            spindac(0,1);
  131.            }
  132.         else if ((dotmode == 11 && colors == 256) || !colors) {
  133.            /* disk video, setvideomode via bios didn't get it right, so: */
  134. #ifndef XFRACT
  135.            ValidateLuts("default"); /* read the default palette file */
  136. #endif
  137.            }
  138.         colorstate = 0;
  139.         }
  140.      if (viewwindow) {
  141.         ftemp = finalaspectratio
  142.             * (double)sydots / (double)sxdots / screenaspect;
  143.         if ((xdots = viewxdots) != 0) { /* xdots specified */
  144.            if ((ydots = viewydots) == 0) /* calc ydots? */
  145.           ydots = (int)((double)xdots * ftemp + 0.5);
  146.            }
  147.         else
  148.            if (finalaspectratio <= screenaspect) {
  149.           xdots = (int)((double)sxdots / viewreduction + 0.5);
  150.           ydots = (int)((double)xdots * ftemp + 0.5);
  151.           }
  152.            else {
  153.           ydots = (int)((double)sydots / viewreduction + 0.5);
  154.           xdots = (int)((double)ydots / ftemp + 0.5);
  155.           }
  156.         if (xdots > sxdots || ydots > sydots) {
  157.            static FCODE msg[] = {"View window too large; using full screen."};
  158.            stopmsg(0,msg);
  159.            xdots = sxdots;
  160.            ydots = sydots;
  161.            }
  162.         else if (xdots <= sxdots/20 || ydots <= sydots/20) { /* so ssg works */
  163.            static FCODE msg[] = {"View window too small; using full screen."};
  164.            stopmsg(0,msg);
  165.            xdots = sxdots;
  166.            ydots = sydots;
  167.            }
  168.         sxoffs = (sxdots - xdots) / 2;
  169.         syoffs = (sydots - ydots) / 3;
  170.         }
  171.      dxsize = xdots - 1;        /* convert just once now */
  172.      dysize = ydots - 1;
  173.      }
  174.       if(savedac == 0)
  175.         savedac = 2;            /* assume we save next time (except jb) */
  176.       else
  177.       savedac = 1;            /* assume we save next time */
  178.       if (initbatch == 0)
  179.      lookatmouse = -PAGE_UP;    /* mouse left button == pgup */
  180.  
  181.       if(showfile == 0) {        /* loading an image */
  182.      outln_cleanup = NULL;        /* outln routine can set this */
  183.      if (display3d)         /* set up 3D decoding */
  184.         outln = call_line3d;
  185.      else if(filetype >= 1)     /* old .tga format input file */
  186.         outln = outlin16;
  187.      else if(comparegif)        /* debug 50 */
  188.         outln = cmp_line;
  189.      else if(pot16bit) {        /* .pot format input file */
  190.         if (pot_startdisk() < 0)
  191.         {                /* pot file failed?  */
  192.            showfile = 1;
  193.            potflag  = 0;
  194.            pot16bit = 0;
  195.            initmode = -1;
  196.            calc_status = 2;        /* "resume" without 16-bit */
  197.            setvideotext();
  198.            get_fracttype();
  199.            /* goto imagestart; */
  200.            return(IMAGESTART);
  201.         }
  202.         outln = pot_line;
  203.      }
  204.      else                /* regular gif/fra input file */
  205.             if(soundflag > 0)
  206.                outln = sound_line;      /* sound decoding */
  207.             else
  208.                outln = out_line;        /* regular decoding */
  209.      if(filetype == 0)
  210.      {
  211.         if(iit == 2 && usr_floatflag != 0)
  212.            if(F4x4Lock()==0)
  213.               iit = -1;  /* semaphore not free - no iit */
  214.         if(debugflag==2224)
  215.          {
  216.             char buf[80];
  217.             sprintf(buf,"iit=%d floatflag=%d",iit,usr_floatflag);
  218.             stopmsg(4,(char far *)buf);
  219.          }
  220.  
  221.         i = funny_glasses_call(gifview);
  222.         if(iit == 2)
  223.            F4x4Free();      /* unlock semaphore */
  224.         else if(iit == -1)
  225.            iit = 2;         /* semaphore operating */
  226.      }
  227.      else
  228.         i = funny_glasses_call(tgaview);
  229.      if(outln_cleanup)        /* cleanup routine defined? */
  230.         (*outln_cleanup)();
  231.      if(i == 0)
  232.         buzzer(0);
  233.      else {
  234.         calc_status = -1;
  235.         if (keypressed()) {
  236.            static FCODE msg[] = {"*** load incomplete ***"};
  237.            buzzer(1);
  238.            while (keypressed()) getakey();
  239.            texttempmsg(msg);
  240.            }
  241.         }
  242.      }
  243.  
  244.       zoomoff = 1;            /* zooming is enabled */
  245.       if (dotmode == 11 || (curfractalspecific->flags&NOZOOM) != 0)
  246.      zoomoff = 0;            /* for these cases disable zooming */
  247.       calcfracinit();
  248. #ifdef XFRACT
  249.       schedulealarm(1);
  250. #endif
  251.  
  252.       sxmin = xxmin; /* save 3 corners for zoom.c ref points */
  253.       sxmax = xxmax;
  254.       sx3rd = xx3rd;
  255.       symin = yymin;
  256.       symax = yymax;
  257.       sy3rd = yy3rd;
  258.  
  259.       if(bf_math)
  260.       {
  261.          copy_bf(bfsxmin,bfxmin);
  262.          copy_bf(bfsxmax,bfxmax);
  263.          copy_bf(bfsymin,bfymin);
  264.          copy_bf(bfsymax,bfymax);
  265.          copy_bf(bfsx3rd,bfx3rd);
  266.          copy_bf(bfsy3rd,bfy3rd);
  267.       }
  268.       save_history_info();
  269.       if (display3d || showfile) {    /* paranoia: these vars don't get set */
  270.      save_system  = active_system;    /*   unless really doing some work,   */
  271.      }                /*   so simple <r> + <s> keeps number */
  272.  
  273.       if(showfile == 0) {        /* image has been loaded */
  274.      showfile = 1;
  275.      if (initbatch == 1 && calc_status == 2)
  276.         initbatch = -1; /* flag to finish calc before save */
  277.      if (loaded3d)        /* 'r' of image created with '3' */
  278.         display3d = 1;  /* so set flag for 'b' command */
  279.      }
  280.       else {                /* draw an image */
  281.      diskisactive = 1;        /* flag for disk-video routines */
  282.      if (initsavetime != 0        /* autosave and resumable? */
  283.        && (curfractalspecific->flags&NORESUME) == 0) {
  284.         savebase = readticker(); /* calc's start time */
  285.         saveticks = abs(initsavetime);
  286.         saveticks *= 1092; /* bios ticks/minute */
  287.         if ((saveticks & 65535L) == 0)
  288.            ++saveticks; /* make low word nonzero */
  289.         finishrow = -1;
  290.         }
  291.      i = calcfract();    /* draw the fractal using "C" */
  292.      if (i == 0)
  293.         buzzer(0); /* finished!! */
  294.  
  295.      saveticks = 0;         /* turn off autosave timer */
  296.      if (dotmode == 11 && i == 0) /* disk-video */
  297.      {
  298.         static FCODE o_msg[] = {"Image has been completed"};
  299.         char msg[sizeof(o_msg)];
  300.         far_strcpy(msg,o_msg);
  301.         dvid_status(0,msg);
  302.      }   
  303.      diskisactive = 0;        /* flag for disk-video routines */
  304.      }
  305.  
  306. #ifndef XFRACT
  307.       boxcount = 0;            /* no zoom box yet  */
  308.       zwidth = 0;
  309. #else
  310.       if (!XZoomWaiting) {
  311.       boxcount = 0;            /* no zoom box yet  */
  312.       zwidth = 0;
  313.       }
  314. #endif
  315.  
  316.       if (fractype == PLASMA && cpu > 88) {
  317.      cyclelimit = 256;        /* plasma clouds need quick spins */
  318.      daccount = 256;
  319.      daclearn = 1;
  320.      }
  321.  
  322. resumeloop:                /* return here on failed overlays */
  323.  
  324.       *kbdmore = 1;
  325.       while (*kbdmore == 1) {        /* loop through command keys */
  326.      if (timedsave != 0) {
  327.         if (timedsave == 1) {    /* woke up for timed save */
  328.            getakey();     /* eat the dummy char */
  329.            kbdchar = 's'; /* do the save */
  330.            resave_flag = 1;
  331.            timedsave = 2;
  332.            }
  333.         else {            /* save done, resume */
  334.            timedsave = 0;
  335.            resave_flag = 2;
  336.            kbdchar = ENTER;
  337.            }
  338.         }
  339.      else if (initbatch == 0) {    /* not batch mode */
  340.         lookatmouse = (zwidth == 0) ? -PAGE_UP : 3;
  341.         if (calc_status == 2 && zwidth == 0 && !keypressed()) {
  342.           kbdchar = ENTER ;  /* no visible reason to stop, continue */
  343.         } else {     /* wait for a real keystroke */
  344.           if (autobrowse && !no_sub_images) kbdchar = 'l';
  345.            else
  346.            {
  347. #ifndef XFRACT
  348.            while (!keypressed());/* { }*/  /* enables help */
  349. #else
  350.            waitkeypressed(0);
  351. #endif
  352.            kbdchar = getakey();
  353.            }
  354.            if (kbdchar == ESC || kbdchar == 'm' || kbdchar == 'M') {
  355.           if (kbdchar == ESC && escape_exit != 0)
  356.               /* don't ask, just get out */
  357.               goodbye();
  358.           stackscreen();
  359. #ifndef XFRACT
  360.           kbdchar = main_menu(1);
  361. #else
  362.           if (XZoomWaiting) {
  363.               kbdchar = ENTER;
  364.           } else {
  365.               kbdchar = main_menu(1);
  366.               if (XZoomWaiting) {
  367.               kbdchar = ENTER;
  368.               }
  369.           }
  370. #endif
  371.           if (kbdchar == '\\' || kbdchar == CTL_BACKSLASH ||
  372.               kbdchar == 'h' || kbdchar == 8 ||
  373.               check_vidmode_key(0,kbdchar) >= 0)
  374.              discardscreen();
  375.           else if (kbdchar == 'x' || kbdchar == 'y' ||
  376.                kbdchar == 'z' || kbdchar == 'g' ||
  377.                kbdchar == 'v' || kbdchar == 2)
  378.              fromtext_flag = 1;
  379.           else 
  380.              unstackscreen();
  381.           }
  382.            }
  383.         }
  384.      else {        /* batch mode, fake next keystroke */
  385.  
  386. /* initbatch == -1  flag to finish calc before save */
  387. /* initbatch == 0   not in batch mode */
  388. /* initbatch == 1   normal batch mode */
  389. /* initbatch == 2   was 1, now do a save */
  390. /* initbatch == 3   bailout with errorlevel == 2, error occurred, no save */
  391. /* initbatch == 4   bailout with errorlevel == 1, interrupted, try to save */
  392. /* initbatch == 5   was 4, now do a save */
  393.  
  394.         if (initbatch == -1) {    /* finish calc */
  395.            kbdchar = ENTER;
  396.            initbatch = 1;
  397.            }
  398.         else if (initbatch == 1 || initbatch == 4 ) {    /* save-to-disk */
  399. /*
  400.            while(keypressed())
  401.          getakey();
  402. */
  403.            if (debugflag == 50)
  404.           kbdchar = 'r';
  405.            else
  406.           kbdchar = 's';
  407.            if(initbatch == 1) initbatch = 2;
  408.            if(initbatch == 4) initbatch = 5;
  409.            }
  410.         else {
  411.            if(calc_status != 4) initbatch = 3; /* bailout with error */
  412.            goodbye();        /* done, exit */
  413.            }
  414.         }
  415.  
  416. #ifndef XFRACT
  417.          if ('A' <= kbdchar && kbdchar <= 'Z')
  418.             kbdchar = tolower(kbdchar);
  419. #endif
  420.  
  421.          switch(main_menu_switch(&kbdchar,&frommandel,kbdmore,stacked,axmode))
  422.          {
  423.          case IMAGESTART:
  424.             return(IMAGESTART);
  425.          case RESTORESTART:
  426.             return(RESTORESTART);
  427.          case RESTART:
  428.             return(RESTART);
  429.          case CONTINUE:
  430.             continue;
  431.          default:
  432.             break;
  433.          }
  434.      if (zoomoff == 1 && *kbdmore == 1) /* draw/clear a zoom box? */
  435.         drawbox(1);
  436. #ifdef XFRACT
  437.      if (resizeWindow()) {
  438.          calc_status = -1;
  439.      }
  440. #endif
  441.      }
  442.       }
  443. /*  return(0); */
  444. }
  445.  
  446. int main_menu_switch(int *kbdchar, int *frommandel, int *kbdmore, char *stacked, int axmode)
  447. {
  448.    int i,k;
  449.    static double  jxxmin, jxxmax, jyymin, jyymax; /* "Julia mode" entry point */
  450.    static double  jxx3rd, jyy3rd;
  451.    /*
  452.    char drive[FILE_MAX_DRIVE];
  453.    char dir[FILE_MAX_DIR];
  454.    char fname[FILE_MAX_FNAME];
  455.    char ext[FILE_MAX_EXT];
  456.    */
  457.    switch (*kbdchar)
  458.    {
  459.    case 't':            /* new fractal type             */
  460.       julibrot = 0;
  461.       clear_zoombox();
  462.       stackscreen();
  463.       if ((i = get_fracttype()) >= 0)
  464.       {
  465.      discardscreen();
  466.      savedac = 0;
  467.      save_release = release;
  468.      no_mag_calc = 0;
  469.      use_old_period = 0;
  470.      if (i == 0)
  471.      {
  472.         initmode = adapter;
  473.         *frommandel = 0;
  474.      }
  475.      else if (initmode < 0)    /* it is supposed to be... */
  476.         setvideotext();    /* reset to text mode       */
  477.      return(IMAGESTART);
  478.       }
  479.       unstackscreen();
  480.       break;
  481.    case 24:            /* Ctl-X, Ctl-Y, CTL-Z do flipping */
  482.    case 25:
  483.    case 26:
  484.       flip_image(*kbdchar);
  485.       break;
  486.    case 'x':            /* invoke options screen        */
  487.    case 'y':
  488.    case 'z':            /* type specific parms */
  489.    case 'g':
  490.    case 'v':
  491.    case 2:
  492.       if (fromtext_flag == 1)
  493.      fromtext_flag = 0;
  494.       else
  495.      stackscreen();
  496.       if (*kbdchar == 'x')
  497.      i = get_toggles();
  498.       else if (*kbdchar == 'y')
  499.      i = get_toggles2();
  500.       else if (*kbdchar == 'z')
  501.      i = get_fract_params(1);
  502.       else if (*kbdchar == 'v')
  503.      i = get_view_params();    /* get the parameters */
  504.       else if (*kbdchar == 2)
  505.      i = get_browse_params();
  506.       else
  507.      i = get_cmd_string();
  508.       unstackscreen();
  509.       if (i > 0)        /* time to redraw? */
  510.      *kbdmore = calc_status = 0;
  511.       break;
  512. #ifndef XFRACT
  513.    case '@':            /* execute commands */
  514.    case '2':            /* execute commands */
  515. #else
  516.    case F2:            /* execute commands */
  517. #endif
  518.       stackscreen();
  519.       i = get_commands();
  520.       if (initmode != -1)
  521.       {                /* video= was specified */
  522.      adapter = initmode;
  523.      initmode = -1;
  524.      i |= 1;
  525.      savedac = 0;
  526.       }
  527.       else if (colorpreloaded)
  528.       {                /* colors= was specified */
  529.      spindac(0, 1);
  530.      colorpreloaded = 0;
  531.       }
  532.       else if ((i & 8))        /* reset was specified */
  533.      savedac = 0;
  534.       if ((i & 4))
  535.       {                /* 3d = was specified */
  536.      *kbdchar = '3';
  537.      unstackscreen();
  538.      goto do_3d_transform;    /* pretend '3' was keyed */
  539.       }
  540.       if ((i & 1))
  541.       {                /* fractal parameter changed */
  542.      discardscreen();
  543.      /* backwards_v18();*/  /* moved this to cmdfiles.c */
  544.      /* backwards_v19();*/
  545.      *kbdmore = calc_status = 0;
  546.       }
  547.       else
  548.      unstackscreen();
  549.       break;
  550.    case 'f':            /* floating pt toggle           */
  551.       if (usr_floatflag == 0)
  552.      usr_floatflag = 1;
  553.       else
  554.      usr_floatflag = 0;
  555.       initmode = adapter;
  556.       return(IMAGESTART);
  557.    case 'i':            /* 3d fractal parms */
  558.       if (get_fract3d_params() >= 0)    /* get the parameters */
  559.      calc_status = *kbdmore = 0;    /* time to redraw */
  560.       break;
  561. #if 0
  562.    case 'w':
  563.       /*chk_keys();*/
  564.       /*julman();*/
  565.       break;
  566. #endif
  567.    case 1:                     /* ^a Ant */
  568.       clear_zoombox();
  569.       {
  570.      int oldtype, err;
  571.      double oldparm[2];
  572.      oldtype = fractype;
  573.      oldparm[0] = param[0];
  574.      oldparm[1] = param[1];
  575.      if (fractype != ANT)
  576.      {
  577.         fractype = ANT;
  578.         curfractalspecific = &fractalspecific[fractype];
  579.         param[0] = curfractalspecific->paramvalue[0];
  580.         param[1] = curfractalspecific->paramvalue[1];
  581.      }
  582.      if (!fromtext_flag)
  583.         stackscreen();
  584.      fromtext_flag = 0;
  585.      if ((err = get_fract_params(2)) >= 0)
  586.      {
  587.         unstackscreen();
  588.         if (ant() >= 0)
  589.            calc_status = 0;
  590.      }
  591.      else
  592.         unstackscreen();
  593.      fractype = oldtype;
  594.      param[0] = oldparm[0];
  595.      param[1] = oldparm[1];
  596.      if (err >= 0)
  597.         return(CONTINUE);
  598.       }
  599.       break;
  600.    case 'k':                    /* ^s is irritating, give user a single key */
  601.    case 19:            /* ^s RDS */
  602.       clear_zoombox();
  603.       if (get_rds_params() >= 0)
  604.       {
  605.      if (do_AutoStereo() >= 0)
  606.         calc_status = 0;
  607.      return(CONTINUE);
  608.       }
  609.       break;
  610.    case 'a':            /* starfield parms               */
  611.       clear_zoombox();
  612.       if (get_starfield_params() >= 0)
  613.       {
  614.      if (starfield() >= 0)
  615.         calc_status = 0;
  616.      return(CONTINUE);
  617.       }
  618.       break;
  619.    case 15:            /* ctrl-o */
  620.    case 'o':
  621.       /* must use standard fractal and have a float variant */
  622.       if ((fractalspecific[fractype].calctype == StandardFractal
  623.        || fractalspecific[fractype].calctype == calcfroth) &&
  624.       (fractalspecific[fractype].isinteger == 0 ||
  625.        fractalspecific[fractype].tofloat != NOFRACTAL) &&
  626.        !bf_math /* for now no arbitrary precision support */ )
  627.       {
  628.      clear_zoombox();
  629.      Jiim(ORBIT);
  630.       }
  631.       break;
  632.    case SPACE:            /* spacebar, toggle mand/julia     */
  633.       if(bf_math)
  634.          break;
  635.       if (fractype == CELLULAR)
  636.       {
  637.      if (nxtscreenflag)
  638.         nxtscreenflag = 0;    /* toggle flag to stop generation */
  639.      else
  640.         nxtscreenflag = 1;    /* toggle flag to generate next screen */
  641.      calc_status = 2;
  642.      *kbdmore = 0;
  643.       }
  644.       else
  645.       {
  646.      if (curfractalspecific->tojulia != NOFRACTAL
  647.          && param[0] == 0.0 && param[1] == 0.0)
  648.      {
  649.         /* switch to corresponding Julia set */
  650.         int key;
  651.         if ((fractype == MANDEL || fractype == MANDELFP) && bf_math == 0)
  652.           hasinverse = 1;
  653.         else
  654.           hasinverse = 0;
  655.         clear_zoombox();
  656.         Jiim(JIIM);
  657.         key = getakey();    /* flush keyboard buffer */
  658.         if (key != SPACE)
  659.         {
  660.           ungetakey(key);
  661.           break;
  662.         }
  663.         fractype = curfractalspecific->tojulia;
  664.         curfractalspecific = &fractalspecific[fractype];
  665.         if (xcjul == BIG || ycjul == BIG)
  666.         {
  667.            param[0] = (xxmax + xxmin) / 2;
  668.            param[1] = (yymax + yymin) / 2;
  669.         }
  670.         else
  671.         {
  672.            param[0] = xcjul;
  673.            param[1] = ycjul;
  674.            xcjul = ycjul = BIG;
  675.         }
  676.         jxxmin = sxmin;
  677.         jxxmax = sxmax;
  678.         jyymax = symax;
  679.         jyymin = symin;
  680.         jxx3rd = sx3rd;
  681.         jyy3rd = sy3rd;
  682.         *frommandel = 1;
  683.         xxmin = curfractalspecific->xmin;
  684.         xxmax = curfractalspecific->xmax;
  685.         yymin = curfractalspecific->ymin;
  686.         yymax = curfractalspecific->ymax;
  687.         xx3rd = xxmin;
  688.         yy3rd = yymin;
  689.         if (usr_distest == 0 && usr_biomorph != -1 && bitshift != 29)
  690.         {
  691.            xxmin *= 3.0;
  692.            xxmax *= 3.0;
  693.            yymin *= 3.0;
  694.            yymax *= 3.0;
  695.            xx3rd *= 3.0;
  696.            yy3rd *= 3.0;
  697.         }
  698.         zoomoff = 1;
  699.         calc_status = 0;
  700.         *kbdmore = 0;
  701.      }
  702.      else if (curfractalspecific->tomandel != NOFRACTAL)
  703.      {
  704.         /* switch to corresponding Mandel set */
  705.         fractype = curfractalspecific->tomandel;
  706.         curfractalspecific = &fractalspecific[fractype];
  707.         if (*frommandel)
  708.         {
  709.            xxmin = jxxmin;
  710.            xxmax = jxxmax;
  711.            yymin = jyymin;
  712.            yymax = jyymax;
  713.            xx3rd = jxx3rd;
  714.            yy3rd = jyy3rd;
  715.         }
  716.         else
  717.         {
  718.            double ccreal, ccimag;
  719.            ccreal = (curfractalspecific->xmax - curfractalspecific->xmin) / 2;
  720.            ccimag = (curfractalspecific->ymax - curfractalspecific->ymin) / 2;
  721.            xxmin = xx3rd = param[0] - ccreal;
  722.            xxmax = param[0] + ccreal;
  723.            yymin = yy3rd = param[1] - ccimag;
  724.            yymax = param[1] + ccimag;
  725.         }
  726.         param[0] = 0;
  727.         param[1] = 0;
  728.         zoomoff = 1;
  729.         calc_status = 0;
  730.         *kbdmore = 0;
  731.      }
  732.      else
  733.         buzzer(2);        /* can't switch */
  734.       }                /* end of else for if == cellular */
  735.       break;
  736.    case 'j':            /* inverse julia toggle */
  737.       /* if the inverse types proliferate, something more elegant will be
  738.        * needed */
  739.       if (fractype == JULIA || fractype == JULIAFP || fractype == INVERSEJULIA)
  740.       {
  741.      static int oldtype = -1;
  742.      if (fractype == JULIA || fractype == JULIAFP)
  743.      {
  744.         oldtype = fractype;
  745.         fractype = INVERSEJULIA;
  746.      }
  747.      else if (fractype == INVERSEJULIA)
  748.      {
  749.         if (oldtype != -1)
  750.            fractype = oldtype;
  751.         else
  752.            fractype = JULIA;
  753.      }
  754.      curfractalspecific = &fractalspecific[fractype];
  755.      zoomoff = 1;
  756.      calc_status = 0;
  757.      *kbdmore = 0;
  758.       }
  759. #if 0
  760.       else if (fractype == MANDEL || fractype == MANDELFP)
  761.       {
  762.      clear_zoombox();
  763.      Jiim(JIIM);
  764.       }
  765. #endif
  766.       else
  767.      buzzer(2);
  768.       break;
  769.    case '\\':            /* return to prev image    */
  770.    case CTL_BACKSLASH:
  771.    case 'h':
  772.    case 8:
  773.       if (name_stack_ptr >= 1)
  774.       {
  775.      /* go back one file if somewhere to go (ie. browsing) */
  776.      name_stack_ptr--;
  777.      strcpy(browsename, file_name_stack[name_stack_ptr]);
  778.      /*
  779.      splitpath(browsename, NULL, NULL, fname, ext);
  780.      splitpath(readname, drive, dir, NULL, NULL);
  781.      makepath(readname, drive, dir, fname, ext);
  782.      */
  783.      merge_pathnames(readname,browsename,2);
  784.      browsing = TRUE;
  785.      no_sub_images = FALSE;
  786.      showfile = 0;
  787.      if (askvideo)
  788.      {
  789.         stackscreen();    /* save graphics image */
  790.         *stacked = 1;
  791.      }
  792.      return(RESTORESTART);
  793.       }
  794.       else if(maxhistory > 0 && bf_math == 0)
  795.       {
  796.          if(*kbdchar == '\\' || *kbdchar == 'h')
  797.         if (--historyptr < 0)
  798.            historyptr = maxhistory - 1;
  799.      if(*kbdchar == CTL_BACKSLASH || *kbdchar == 8)
  800.         if (++historyptr >= maxhistory)
  801.            historyptr = 0;
  802.          restore_history_info(historyptr);
  803.      zoomoff = 1;
  804.      initmode = adapter;
  805.      if (curfractalspecific->isinteger != 0 &&
  806.          curfractalspecific->tofloat != NOFRACTAL)
  807.         usr_floatflag = 0;
  808.      if (curfractalspecific->isinteger == 0 &&
  809.          curfractalspecific->tofloat != NOFRACTAL)
  810.         usr_floatflag = 1;
  811.      historyflag = 1;    /* avoid re-store parms due to rounding errs */
  812.      return(IMAGESTART);
  813.       }
  814.       break;
  815.    case 'd':            /* shell to MS-DOS              */
  816.       stackscreen();
  817. #ifndef XFRACT
  818.       if (axmode == 0 || axmode > 7)
  819.       {
  820.      static FCODE dosmsg[] =
  821.      {"\
  822. Note:  Your graphics image is still squirreled away in your video\n\
  823. adapter's memory.  Switching video modes will clobber part of that\n\
  824. image.  Sorry - it's the best we could do."};
  825.      putstring(0, 0, 7, dosmsg);
  826.      movecursor(6, 0);
  827.       }
  828. #endif
  829.       shell_to_dos();
  830.       unstackscreen();
  831. /*           calc_status = 0; */
  832.       break;
  833.    case 'c':            /* switch to color cycling      */
  834.    case '+':            /* rotate palette               */
  835.    case '-':            /* rotate palette               */
  836.       clear_zoombox();
  837.       memcpy(olddacbox, dacbox, 256 * 3);
  838.       rotate((*kbdchar == 'c') ? 0 : ((*kbdchar == '+') ? 1 : -1));
  839.       if (memcmp(olddacbox, dacbox, 256 * 3))
  840.       {
  841.      colorstate = 1;
  842.          save_history_info();
  843.       }   
  844.       return(CONTINUE);
  845.    case 'e':            /* switch to color editing      */
  846.       clear_zoombox();
  847.       if (dacbox[0][0] != 255 && !reallyega && colors >= 16
  848.       && dotmode != 11)
  849.       {
  850.      int oldhelpmode;
  851.      oldhelpmode = helpmode;
  852.      memcpy(olddacbox, dacbox, 256 * 3);
  853.      helpmode = HELPXHAIR;
  854.      EditPalette();
  855.      helpmode = oldhelpmode;
  856.      if (memcmp(olddacbox, dacbox, 256 * 3))
  857.          {
  858.         colorstate = 1;
  859.             save_history_info();
  860.          }   
  861.       }
  862.       return(CONTINUE);
  863.    case 's':            /* save-to-disk                 */
  864.       diskisactive = 1;        /* flag for disk-video routines */
  865.       note_zoom();
  866.       savetodisk(savename);
  867.       restore_zoom();
  868.       diskisactive = 0;        /* flag for disk-video routines */
  869.       return(CONTINUE);
  870.    case '#':            /* 3D overlay                   */
  871. #ifdef XFRACT
  872.    case F3:            /* 3D overlay                   */
  873. #endif
  874.       clear_zoombox();
  875.       overlay3d = 1;
  876.    case '3':            /* restore-from (3d)            */
  877.     do_3d_transform:
  878.       if (overlay3d)
  879.      display3d = 2;        /* for <b> command          */
  880.       else
  881.      display3d = 1;
  882.    case 'r':            /* restore-from                 */
  883.       comparegif = 0;
  884.       *frommandel = 0;
  885.       if (browsing)
  886.       {
  887.      browsing = FALSE;
  888.       }
  889.       if (*kbdchar == 'r')
  890.       {
  891.      if (debugflag == 50)
  892.      {
  893.         comparegif = overlay3d = 1;
  894.         if (initbatch == 2)
  895.         {
  896.            stackscreen();    /* save graphics image */
  897.            strcpy(readname, savename);
  898.            showfile = 0;
  899.            return(RESTORESTART);
  900.         }
  901.      }
  902.      else
  903.         comparegif = overlay3d = 0;
  904.      display3d = 0;
  905.       }
  906.       stackscreen();        /* save graphics image */
  907.       if (overlay3d)
  908.      *stacked = 0;
  909.       else
  910.      *stacked = 1;
  911.       if (resave_flag)
  912.       {
  913.      updatesavename(savename);    /* do the pending increment */
  914.      resave_flag = started_resaves = 0;
  915.       }
  916.       showfile = -1;
  917.       return(RESTORESTART);
  918.       /* RB */
  919.    case 'l':
  920.    case 'L':            /* Look for other files within this view */
  921.       if ((zwidth == 0) && (!diskvideo))    /* not zooming & no disk
  922.                          * video */
  923.       {
  924.      int oldhelpmode;
  925.      oldhelpmode = helpmode;
  926.      helpmode = HELPBROWSE;
  927.      switch (fgetwindow())
  928.      {
  929.      case ENTER:
  930.      case ENTER_2:
  931.         showfile = 0;    /* trigger load */
  932.         browsing = TRUE;    /* but don't ask for the file name as it's
  933.                  * just been selected */
  934.         if (name_stack_ptr == 15)
  935.         {            /* about to run off the end of the file
  936.                  * history stack so shift it all back one to
  937.                  * make room, lose the 1st one */
  938.            int tmp;
  939.            for (tmp = 1; tmp < 16; tmp++)
  940.           strcpy(file_name_stack[tmp - 1], file_name_stack[tmp]);
  941.            name_stack_ptr = 14;
  942.         }
  943.         name_stack_ptr++;
  944.         strcpy(file_name_stack[name_stack_ptr], browsename);
  945.         /*
  946.         splitpath(browsename, NULL, NULL, fname, ext);
  947.         splitpath(readname, drive, dir, NULL, NULL);
  948.         makepath(readname, drive, dir, fname, ext);
  949.         */
  950.         merge_pathnames(readname,browsename,2);
  951.         if (askvideo)
  952.         {
  953.            stackscreen();    /* save graphics image */
  954.            *stacked = 1;
  955.         }
  956.         return(RESTORESTART);    /* hop off and do it!! */
  957.      case '\\':
  958.         if (name_stack_ptr >= 1)
  959.         {
  960.            /* go back one file if somewhere to go (ie. browsing) */
  961.            name_stack_ptr--;
  962.            strcpy(browsename, file_name_stack[name_stack_ptr]);
  963.            /*
  964.            splitpath(browsename, NULL, NULL, fname, ext);
  965.            splitpath(readname, drive, dir, NULL, NULL);
  966.            makepath(readname, drive, dir, fname, ext);
  967.            */
  968.            merge_pathnames(readname,browsename,2);
  969.            browsing = TRUE;
  970.            showfile = 0;
  971.            if (askvideo)
  972.            {
  973.           stackscreen();/* save graphics image */
  974.           *stacked = 1;
  975.            }
  976.            return(RESTORESTART);
  977.         }            /* otherwise fall through and turn off
  978.                  * browsing */
  979.      case ESC:
  980.      case 'l':        /* turn it off */
  981.      case 'L':
  982.         browsing = FALSE;
  983.         helpmode = oldhelpmode;
  984.         break;
  985.      case 's':
  986.         browsing = FALSE;
  987.         helpmode = oldhelpmode;
  988.         savetodisk(savename);
  989.         break;
  990.      default:        /* or no files found, leave the state of
  991.                  * browsing */
  992.         break;        /* alone */
  993.      }
  994.       }
  995.       else
  996.       {
  997.      browsing = FALSE;
  998.      buzzer(2);        /* can't browse if zooming or diskvideo */
  999.       }
  1000.       break;
  1001.    case 'b':            /* make batch file              */
  1002.       make_batch_file();
  1003.       break;
  1004.    case 'p':            /* print current image          */
  1005.       note_zoom();
  1006.       Print_Screen();
  1007.       restore_zoom();
  1008.       if (!keypressed())
  1009.      buzzer(0);
  1010.       else
  1011.       {
  1012.      buzzer(1);
  1013.      getakey();
  1014.       }
  1015.       return(CONTINUE);
  1016.    case ENTER:            /* Enter                        */
  1017.    case ENTER_2:        /* Numeric-Keypad Enter         */
  1018. #ifdef XFRACT
  1019.       XZoomWaiting = 0;
  1020. #endif
  1021.       if (zwidth != 0.0)
  1022.       {                /* do a zoom */
  1023.      init_pan_or_recalc(0);
  1024.      *kbdmore = 0;
  1025.       }
  1026.       if (calc_status != 4)    /* don't restart if image complete */
  1027.      *kbdmore = 0;
  1028.       break;
  1029.    case CTL_ENTER:        /* control-Enter                */
  1030.    case CTL_ENTER_2:        /* Control-Keypad Enter         */
  1031.       init_pan_or_recalc(1);
  1032.       *kbdmore = 0;
  1033.       zoomout();        /* calc corners for zooming out */
  1034.       break;
  1035.    case INSERT:        /* insert                       */
  1036.       setvideotext();        /* force text mode */
  1037.       return(RESTART);
  1038.    case LEFT_ARROW:        /* cursor left                  */
  1039.    case RIGHT_ARROW:        /* cursor right                 */
  1040.    case UP_ARROW:        /* cursor up                    */
  1041.    case DOWN_ARROW:        /* cursor down                  */
  1042.    case LEFT_ARROW_2:        /* Ctrl-cursor left             */
  1043.    case RIGHT_ARROW_2:        /* Ctrl-cursor right            */
  1044.    case UP_ARROW_2:        /* Ctrl-cursor up               */
  1045.    case DOWN_ARROW_2:        /* Ctrl-cursor down             */
  1046.       move_zoombox(*kbdchar);
  1047.       break;
  1048.    case CTL_HOME:        /* Ctrl-home                    */
  1049.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1050.       {
  1051.      i = key_count(CTL_HOME);
  1052.      if ((zskew -= 0.02 * i) < -0.48)
  1053.         zskew = -0.48;
  1054.       }
  1055.       break;
  1056.    case CTL_END:        /* Ctrl-end                     */
  1057.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1058.       {
  1059.      i = key_count(CTL_END);
  1060.      if ((zskew += 0.02 * i) > 0.48)
  1061.         zskew = 0.48;
  1062.       }
  1063.       break;
  1064.    case CTL_PAGE_UP:        /* Ctrl-pgup                    */
  1065.       if (boxcount)
  1066.      chgboxi(0, -2 * key_count(CTL_PAGE_UP));
  1067.       break;
  1068.    case CTL_PAGE_DOWN:        /* Ctrl-pgdn                    */
  1069.       if (boxcount)
  1070.      chgboxi(0, 2 * key_count(CTL_PAGE_DOWN));
  1071.       break;
  1072.    case PAGE_UP:        /* page up                      */
  1073.       if (zoomoff == 1)
  1074.      if (zwidth == 0)
  1075.      {            /* start zoombox */
  1076.         zwidth = zdepth = 1;
  1077.         zskew = zrotate = 0;
  1078.         zbx = zby = 0;
  1079.         find_special_colors();
  1080.         boxcolor = color_bright;
  1081.      }
  1082.      else
  1083.         resizebox(0 - key_count(PAGE_UP));
  1084.       break;
  1085.    case PAGE_DOWN:        /* page down                    */
  1086.       if (boxcount)
  1087.       {
  1088.      if (zwidth >= .999 && zdepth >= 0.999)    /* end zoombox */
  1089.         zwidth = 0;
  1090.      else
  1091.         resizebox(key_count(PAGE_DOWN));
  1092.       }
  1093.       break;
  1094.    case CTL_MINUS:        /* Ctrl-kpad-                  */
  1095.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1096.      zrotate += key_count(CTL_MINUS);
  1097.       break;
  1098.    case CTL_PLUS:        /* Ctrl-kpad+               */
  1099.       if (boxcount && (curfractalspecific->flags & NOROTATE) == 0)
  1100.      zrotate -= key_count(CTL_PLUS);
  1101.       break;
  1102.    case CTL_INSERT:        /* Ctrl-ins                 */
  1103.       boxcolor += key_count(CTL_INSERT);
  1104.       break;
  1105.    case CTL_DEL:        /* Ctrl-del                 */
  1106.       boxcolor -= key_count(CTL_DEL);
  1107.       break;
  1108.    case DELETE:        /* select video mode from list */
  1109.       stackscreen();
  1110.       *kbdchar = select_video_mode(adapter);
  1111.       if (check_vidmode_key(0, *kbdchar) >= 0)    /* picked a new mode? */
  1112.      discardscreen();
  1113.       else
  1114.      unstackscreen();
  1115.       /* fall through */
  1116.    default:            /* other (maybe a valid Fn key) */
  1117.       if ((k = check_vidmode_key(0, *kbdchar)) >= 0)
  1118.       {
  1119.      adapter = k;
  1120. /*          if (videotable[adapter].dotmode != 11       Took out so that */
  1121. /*            || videotable[adapter].colors != colors)  DAC is not reset */
  1122. /*             savedac = 0;                    when changing video modes */
  1123.      calc_status = 0;
  1124.      *kbdmore = 0;
  1125.      return(CONTINUE);
  1126.       }
  1127.       break;
  1128.    }                /* end of the big switch */
  1129.    return(0);
  1130. }
  1131.  
  1132. static int call_line3d(BYTE *pixels, int linelen)
  1133. {
  1134.    /* this routine exists because line3d might be in an overlay */
  1135.    return(line3d(pixels,linelen));
  1136. }
  1137.  
  1138. static void note_zoom()
  1139. {
  1140.    if (boxcount) { /* save zoombox stuff in far mem before encode (mem reused) */
  1141.       if ((savezoom = farmemalloc((long)(5*boxcount))) == NULL)
  1142.      clear_zoombox(); /* not enuf mem so clear the box */
  1143.       else {
  1144.      reset_zoom_corners(); /* reset these to overall image, not box */
  1145.      far_memcpy(savezoom,boxx,boxcount*2);
  1146.      far_memcpy(savezoom+boxcount*2,boxy,boxcount*2);
  1147.      far_memcpy(savezoom+boxcount*4,boxvalues,boxcount);
  1148.      }
  1149.       }
  1150. }
  1151.  
  1152. static void restore_zoom()
  1153. {
  1154.    if (boxcount) { /* restore zoombox arrays */
  1155.       far_memcpy(boxx,savezoom,boxcount*2);
  1156.       far_memcpy(boxy,savezoom+boxcount*2,boxcount*2);
  1157.       far_memcpy(boxvalues,savezoom+boxcount*4,boxcount);
  1158.       farmemfree(savezoom);
  1159.       drawbox(1); /* get the xxmin etc variables recalc'd by redisplaying */
  1160.       }
  1161. }
  1162.  
  1163. /* do all pending movement at once for smooth mouse diagonal moves */
  1164. static void move_zoombox(int keynum)
  1165. {  int vertical, horizontal, getmore;
  1166.    if (boxcount == 0)
  1167.       return;
  1168.    vertical = horizontal = 0;
  1169.    getmore = 1;
  1170.    while (getmore) {
  1171.       switch (keynum) {
  1172.          case LEFT_ARROW:               /* cursor left */
  1173.             --horizontal;
  1174.             break;
  1175.          case RIGHT_ARROW:              /* cursor right */
  1176.             ++horizontal;
  1177.             break;
  1178.          case UP_ARROW:                 /* cursor up */
  1179.             --vertical;
  1180.             break;
  1181.          case DOWN_ARROW:               /* cursor down */
  1182.             ++vertical;
  1183.             break;
  1184.          case LEFT_ARROW_2:             /* Ctrl-cursor left */
  1185.             horizontal -= 5;
  1186.             break;
  1187.          case RIGHT_ARROW_2:             /* Ctrl-cursor right */
  1188.             horizontal += 5;
  1189.             break;
  1190.          case UP_ARROW_2:               /* Ctrl-cursor up */
  1191.             vertical -= 5;
  1192.             break;
  1193.          case DOWN_ARROW_2:             /* Ctrl-cursor down */
  1194.         vertical += 5;
  1195.         break;
  1196.      default:
  1197.         getmore = 0;
  1198.      }
  1199.       if (getmore) {
  1200.      if (getmore == 2)        /* eat last key used */
  1201.         getakey();
  1202.      getmore = 2;
  1203.      keynum = keypressed();     /* next pending key */
  1204.      }
  1205.       }
  1206.    if (horizontal != 0)
  1207.       moveboxf((double)horizontal/dxsize,0.0);
  1208.    if (vertical != 0)
  1209.       moveboxf(0.0,(double)vertical/dysize);
  1210. }
  1211.  
  1212. /* displays differences between current image file and new image */
  1213. static FILE *cmp_fp;
  1214. static errcount;
  1215. int cmp_line(BYTE *pixels, int linelen)
  1216. {
  1217.    int row,col;
  1218.    int oldcolor;
  1219.    if((row = rowcount++) == 0) {
  1220.       errcount = 0;
  1221.       cmp_fp = dir_fopen(workdir,"cmperr",(initbatch)?"a":"w");
  1222.       outln_cleanup = cmp_line_cleanup;
  1223.       }
  1224.    if(pot16bit) { /* 16 bit info, ignore odd numbered rows */
  1225.       if((row & 1) != 0) return(0);
  1226.       row >>= 1;
  1227.       }
  1228.    for(col=0;col<linelen;col++) {
  1229.       oldcolor=getcolor(col,row);
  1230.       if(oldcolor==(int)pixels[col])
  1231.      putcolor(col,row,0);
  1232.       else {
  1233.      if(oldcolor==0)
  1234.         putcolor(col,row,1);
  1235.      ++errcount;
  1236.      if(initbatch == 0)
  1237.         fprintf(cmp_fp,"#%5d col %3d row %3d old %3d new %3d\n",
  1238.            errcount,col,row,oldcolor,pixels[col]);
  1239.      }
  1240.       }
  1241.    return(0);
  1242. }
  1243.  
  1244. static void cmp_line_cleanup(void)
  1245. {
  1246.    char *timestring;
  1247.    time_t ltime;
  1248.    if(initbatch) {
  1249.       time(<ime);
  1250.       timestring = ctime(<ime);
  1251.       timestring[24] = 0; /*clobber newline in time string */
  1252.       fprintf(cmp_fp,"%s compare to %s has %5d errs\n",
  1253.              timestring,readname,errcount);
  1254.       }
  1255.    fclose(cmp_fp);
  1256. }
  1257.  
  1258. int pot_line(BYTE *pixels, int linelen)
  1259. {
  1260.    int row,col,saverowcount;
  1261.    if (rowcount == 0)
  1262.       if (pot_startdisk() < 0)
  1263.      return -1;
  1264.    saverowcount = rowcount;
  1265.    row = (rowcount >>= 1);
  1266.    if ((saverowcount & 1) != 0) /* odd line */
  1267.       row += ydots;
  1268.    else             /* even line */
  1269.       if (dotmode != 11) /* display the line too */
  1270.      out_line(pixels,linelen);
  1271.    for (col = 0; col < xdots; ++col)
  1272.       writedisk(col+sxoffs,row+syoffs,*(pixels+col));
  1273.    rowcount = saverowcount + 1;
  1274.    return(0);
  1275. }
  1276.  
  1277. void clear_zoombox()
  1278. {
  1279.    zwidth = 0;
  1280.    drawbox(0);
  1281.    reset_zoom_corners();
  1282. }
  1283.  
  1284. void reset_zoom_corners()
  1285. {
  1286.    xxmin = sxmin;
  1287.    xxmax = sxmax;
  1288.    xx3rd = sx3rd;
  1289.    yymax = symax;
  1290.    yymin = symin;
  1291.    yy3rd = sy3rd;
  1292.    if(bf_math)
  1293.    {
  1294.       copy_bf(bfxmin,bfsxmin);
  1295.       copy_bf(bfxmax,bfsxmax);
  1296.       copy_bf(bfymin,bfsymin);
  1297.       copy_bf(bfymax,bfsymax);
  1298.       copy_bf(bfx3rd,bfsx3rd);
  1299.       copy_bf(bfy3rd,bfsy3rd);
  1300.    }
  1301. }
  1302.  
  1303. /*
  1304.    Function setup287code is called by main() when a 287
  1305.    or better fpu is detected.
  1306. */
  1307. #define ORBPTR(x) fractalspecific[x].orbitcalc
  1308. void setup287code()
  1309. {
  1310.    ORBPTR(MANDELFP)      = ORBPTR(JULIAFP)     = FJuliafpFractal;
  1311.    ORBPTR(BARNSLEYM1FP)   = ORBPTR(BARNSLEYJ1FP) = FBarnsley1FPFractal;
  1312.    ORBPTR(BARNSLEYM2FP)   = ORBPTR(BARNSLEYJ2FP) = FBarnsley2FPFractal;
  1313.    ORBPTR(MANOWARFP)      = ORBPTR(MANOWARJFP)     = FManOWarfpFractal;
  1314.    ORBPTR(MANDELLAMBDAFP) = ORBPTR(LAMBDAFP)     = FLambdaFPFractal;
  1315. }
  1316.  
  1317. int sound_line(BYTE *pixels, int linelen)
  1318. {
  1319.    int i;
  1320.    for(i=0;i<linelen;i++)
  1321.    {
  1322.       putcolor(i,rowcount,pixels[i]);
  1323.       if(orbit_delay > 0)
  1324.          sleepms(orbit_delay);
  1325.       snd((int)(pixels[i]*3000/colors+basehertz));
  1326.       if(keypressed())
  1327.       {
  1328.         nosnd();
  1329.         return(-1);
  1330.       }
  1331.    }
  1332.    nosnd();
  1333.    rowcount++;
  1334.    return(0);
  1335. }
  1336.  
  1337. /* read keystrokes while = specified key, return 1+count;    */
  1338. /* used to catch up when moving zoombox is slower than keyboard */
  1339. int key_count(int keynum)
  1340. {  int ctr;
  1341.    ctr = 1;
  1342.    while (keypressed() == keynum) {
  1343.       getakey();
  1344.       ++ctr;
  1345.       }
  1346.    return ctr;
  1347. }
  1348.  
  1349. static void _fastcall save_history_info()
  1350. {
  1351.    HISTORY current;
  1352.    if(maxhistory <= 0 || bf_math)
  1353.       return;
  1354.    far_memset((void far *)¤t,0,sizeof(HISTORY));
  1355.    current.fractal_type    = (short)fractype                  ;
  1356.    current.xmin          = xxmin                     ;
  1357.    current.xmax          = xxmax                     ;
  1358.    current.ymin          = yymin                     ;
  1359.    current.ymax          = yymax                     ;
  1360.    current.creal          = param[0]                  ;
  1361.    current.cimag          = param[1]                  ;
  1362.    current.dparm3          = param[2]                  ;
  1363.    current.dparm4          = param[3]                  ;
  1364.    current.dparm5          = param[4]                  ;
  1365.    current.dparm6          = param[5]                  ;
  1366.    current.dparm7          = param[6]                  ;
  1367.    current.dparm8          = param[7]                  ;
  1368.    current.dparm9          = param[8]                  ;
  1369.    current.dparm10         = param[9]                  ;
  1370.    current.fillcolor          = (short)fillcolor                 ;
  1371.    current.potential[0]    = potparam[0]               ;
  1372.    current.potential[1]    = potparam[1]               ;
  1373.    current.potential[2]    = potparam[2]               ;
  1374.    current.rflag          = (short)rflag                     ;
  1375.    current.rseed          = (short)rseed                     ;
  1376.    current.inside          = (short)inside                    ;
  1377.    current.logmap          = (short)LogFlag                   ;
  1378.    current.invert[0]       = inversion[0]              ;
  1379.    current.invert[1]       = inversion[1]              ;
  1380.    current.invert[2]       = inversion[2]              ;
  1381.    current.decomp          = (short)decomp[0];                ;
  1382.    current.biomorph        = (short)biomorph                  ;
  1383.    current.symmetry          = (short)forcesymmetry             ;
  1384.    current.init3d[0]       = (short)init3d[0]                 ;
  1385.    current.init3d[1]       = (short)init3d[1]                 ;
  1386.    current.init3d[2]       = (short)init3d[2]                 ;
  1387.    current.init3d[3]       = (short)init3d[3]                 ;
  1388.    current.init3d[4]       = (short)init3d[4]                 ;
  1389.    current.init3d[5]       = (short)init3d[5]                 ;
  1390.    current.init3d[6]       = (short)init3d[6]                 ;
  1391.    current.init3d[7]       = (short)init3d[7]                 ;
  1392.    current.init3d[8]       = (short)init3d[8]                 ;
  1393.    current.init3d[9]       = (short)init3d[9]                 ;
  1394.    current.init3d[10]       = (short)init3d[10]               ;
  1395.    current.init3d[11]       = (short)init3d[12]               ;
  1396.    current.init3d[12]       = (short)init3d[13]               ;
  1397.    current.init3d[13]       = (short)init3d[14]               ;
  1398.    current.init3d[14]       = (short)init3d[15]               ;
  1399.    current.init3d[15]       = (short)init3d[16]               ;
  1400.    current.previewfactor   = (short)previewfactor             ;
  1401.    current.xtrans          = (short)xtrans                    ;
  1402.    current.ytrans          = (short)ytrans                    ;
  1403.    current.red_crop_left   = (short)red_crop_left             ;
  1404.    current.red_crop_right  = (short)red_crop_right            ;
  1405.    current.blue_crop_left  = (short)blue_crop_left            ;
  1406.    current.blue_crop_right = (short)blue_crop_right           ;
  1407.    current.red_bright      = (short)red_bright                ;
  1408.    current.blue_bright     = (short)blue_bright               ;
  1409.    current.xadjust          = (short)xadjust                   ;
  1410.    current.yadjust          = (short)yadjust                   ;
  1411.    current.eyeseparation   = (short)eyeseparation             ;
  1412.    current.glassestype     = (short)glassestype               ;
  1413.    current.outside          = (short)outside                   ;
  1414.    current.x3rd          = xx3rd                     ;
  1415.    current.y3rd          = yy3rd                     ;
  1416.    current.stdcalcmode     = stdcalcmode               ;
  1417.    current.three_pass      = three_pass                ;
  1418.    current.distest          = (short)distest                   ;
  1419.    current.trigndx[0]      = trigndx[0]                ;
  1420.    current.trigndx[1]      = trigndx[1]                ;
  1421.    current.trigndx[2]      = trigndx[2]                ;
  1422.    current.trigndx[3]      = trigndx[3]                ;
  1423.    current.finattract      = (short)finattract                ;
  1424.    current.initorbit[0]    = initorbit.x               ;
  1425.    current.initorbit[1]    = initorbit.y               ;
  1426.    current.useinitorbit    = useinitorbit              ;
  1427.    current.periodicity     = (short)periodicitycheck          ;
  1428.    current.pot16bit          = (short)disk16bit                 ;
  1429.    current.release          = (short)release                   ;
  1430.    current.save_release    = (short)save_release              ;
  1431.    current.flag3d          = (short)display3d                 ;
  1432.    current.ambient          = (short)Ambient                   ;
  1433.    current.randomize       = (short)RANDOMIZE                 ;
  1434.    current.haze          = (short)haze                      ;
  1435.    current.transparent[0]  = (short)transparent[0]            ;
  1436.    current.transparent[1]  = (short)transparent[1]            ;
  1437.    current.rotate_lo       = (short)rotate_lo                 ;
  1438.    current.rotate_hi       = (short)rotate_hi                 ;
  1439.    current.distestwidth    = (short)distestwidth              ;
  1440.    current.mxmaxfp         = mxmaxfp                   ;
  1441.    current.mxminfp         = mxminfp                   ;
  1442.    current.mymaxfp         = mymaxfp                   ;
  1443.    current.myminfp         = myminfp                   ;
  1444.    current.zdots           = (short)zdots                  ;
  1445.    current.originfp        = originfp                  ;
  1446.    current.depthfp         = depthfp                      ;
  1447.    current.heightfp        = heightfp                  ;
  1448.    current.widthfp         = widthfp                      ;
  1449.    current.distfp          = distfp                      ;
  1450.    current.eyesfp          = eyesfp                      ;
  1451.    current.orbittype       = (short)neworbittype              ;
  1452.    current.juli3Dmode      = (short)juli3Dmode                ;
  1453.    current.maxfn           = maxfn                     ;
  1454.    current.major_method    = (short)major_method              ;
  1455.    current.minor_method    = (short)minor_method              ;
  1456.    current.bailout         = bailout                   ;
  1457.    current.bailoutest      = (short)bailoutest                ;
  1458.    current.iterations      = maxit                     ;
  1459.    current.old_demm_colors = (short)old_demm_colors;
  1460.    far_memcpy(current.dac,dacbox,256*3);
  1461.    switch(fractype)
  1462.    {
  1463.    case FORMULA:
  1464.    case FFORMULA:
  1465.       far_strncpy(current.filename,FormFileName,80);
  1466.       far_strncpy(current.itemname,FormName,ITEMNAMELEN+1);
  1467.       break;
  1468.    case IFS:
  1469.    case IFS3D:
  1470.       far_strncpy(current.filename,IFSFileName,80);
  1471.       far_strncpy(current.itemname,IFSName,ITEMNAMELEN+1);
  1472.       break;
  1473.    case LSYSTEM:
  1474.       far_strncpy(current.filename,LFileName,80);
  1475.       far_strncpy(current.itemname,LName,ITEMNAMELEN+1);
  1476.       break;
  1477.    default:
  1478.       *(current.filename) = 0;
  1479.       *(current.itemname) = 0;
  1480.       break;
  1481.    }
  1482.    if (historyptr == -1)    /* initialize the history file */
  1483.    {
  1484.       int i;
  1485.       for (i = 0; i < maxhistory; i++) 
  1486.          history[i] = current;
  1487.       historyflag = saveptr = historyptr = 0;    /* initialize history ptr */
  1488.    }
  1489.    else if(historyflag == 1)
  1490.       historyflag = 0;   /* coming from user history command, don't save */
  1491.    else if(far_memcmp(¤t,&history[saveptr],sizeof(HISTORY)))
  1492.    {
  1493.       char msg[80];
  1494.       if(++saveptr >= maxhistory)  /* back to beginning of circular buffer */
  1495.          saveptr = 0; 
  1496.       if(++historyptr >= maxhistory)  /* move user pointer in parallel */
  1497.          historyptr = 0; 
  1498.       history[saveptr] = current;
  1499.       sprintf(msg,"saving image in history %d",saveptr);
  1500.       /* stopmsg(0,msg); */
  1501.    }
  1502. }
  1503.  
  1504. static void _fastcall restore_history_info(int i)
  1505. {
  1506.    char msg[80];
  1507.    sprintf(msg,"restoring msg %d",i);
  1508.    /* stopmsg(0,msg); */
  1509.    if(maxhistory <= 0 || bf_math)
  1510.       return;
  1511.    invert = 0;
  1512.    calc_status = 0;
  1513.    resuming = 0;
  1514.    fractype              = history[i].fractal_type   ;
  1515.    xxmin                 = history[i].xmin         ;
  1516.    xxmax                 = history[i].xmax         ;
  1517.    yymin                 = history[i].ymin         ;
  1518.    yymax                 = history[i].ymax         ;
  1519.    param[0]              = history[i].creal         ;
  1520.    param[1]              = history[i].cimag         ;
  1521.    param[2]              = history[i].dparm3         ;
  1522.    param[3]              = history[i].dparm4         ;
  1523.    param[4]              = history[i].dparm5         ;
  1524.    param[5]              = history[i].dparm6         ;
  1525.    param[6]              = history[i].dparm7         ;
  1526.    param[7]              = history[i].dparm8         ;
  1527.    param[8]              = history[i].dparm9         ;
  1528.    param[9]              = history[i].dparm10        ;
  1529.    fillcolor             = history[i].fillcolor         ;
  1530.    potparam[0]           = history[i].potential[0]   ;
  1531.    potparam[1]           = history[i].potential[1]   ;
  1532.    potparam[2]           = history[i].potential[2]   ;
  1533.    rflag                 = history[i].rflag         ;
  1534.    rseed                 = history[i].rseed         ;
  1535.    inside                = history[i].inside         ;
  1536.    LogFlag               = history[i].logmap         ;
  1537.    inversion[0]          = history[i].invert[0]      ;
  1538.    inversion[1]          = history[i].invert[1]      ;
  1539.    inversion[2]          = history[i].invert[2]      ;
  1540.    decomp[0]             = history[i].decomp         ;
  1541.    usr_biomorph          = history[i].biomorph       ;
  1542.    biomorph              = history[i].biomorph         ;
  1543.    forcesymmetry         = history[i].symmetry         ;
  1544.    init3d[0]             = history[i].init3d[0]      ;
  1545.    init3d[1]             = history[i].init3d[1]      ;
  1546.    init3d[2]             = history[i].init3d[2]      ;
  1547.    init3d[3]             = history[i].init3d[3]      ;
  1548.    init3d[4]             = history[i].init3d[4]      ;
  1549.    init3d[5]             = history[i].init3d[5]      ;
  1550.    init3d[6]             = history[i].init3d[6]      ;
  1551.    init3d[7]             = history[i].init3d[7]      ;
  1552.    init3d[8]             = history[i].init3d[8]      ;
  1553.    init3d[9]             = history[i].init3d[9]      ;
  1554.    init3d[10]            = history[i].init3d[10]     ;
  1555.    init3d[12]            = history[i].init3d[11]     ;
  1556.    init3d[13]            = history[i].init3d[12]     ;
  1557.    init3d[14]            = history[i].init3d[13]     ;
  1558.    init3d[15]            = history[i].init3d[14]     ;
  1559.    init3d[16]            = history[i].init3d[15]     ;
  1560.    previewfactor         = history[i].previewfactor  ;
  1561.    xtrans                = history[i].xtrans         ;
  1562.    ytrans                = history[i].ytrans         ;
  1563.    red_crop_left         = history[i].red_crop_left  ;
  1564.    red_crop_right        = history[i].red_crop_right ;
  1565.    blue_crop_left        = history[i].blue_crop_left ;
  1566.    blue_crop_right       = history[i].blue_crop_right;
  1567.    red_bright            = history[i].red_bright     ;
  1568.    blue_bright           = history[i].blue_bright    ;
  1569.    xadjust               = history[i].xadjust         ;
  1570.    yadjust               = history[i].yadjust         ;
  1571.    eyeseparation         = history[i].eyeseparation  ;
  1572.    glassestype           = history[i].glassestype    ;
  1573.    outside               = history[i].outside         ;
  1574.    xx3rd                 = history[i].x3rd         ;
  1575.    yy3rd                 = history[i].y3rd         ;
  1576.    usr_stdcalcmode       = history[i].stdcalcmode    ;
  1577.    stdcalcmode           = history[i].stdcalcmode    ;
  1578.    three_pass            = history[i].three_pass     ;
  1579.    distest               = history[i].distest         ;
  1580.    usr_distest           = history[i].distest        ;
  1581.    trigndx[0]            = history[i].trigndx[0]     ;
  1582.    trigndx[1]            = history[i].trigndx[1]     ;
  1583.    trigndx[2]            = history[i].trigndx[2]     ;
  1584.    trigndx[3]            = history[i].trigndx[3]     ;
  1585.    finattract            = history[i].finattract     ;
  1586.    initorbit.x           = history[i].initorbit[0]   ;
  1587.    initorbit.y           = history[i].initorbit[1]   ;
  1588.    useinitorbit          = history[i].useinitorbit   ;
  1589.    periodicitycheck      = history[i].periodicity    ;
  1590.    usr_periodicitycheck  = history[i].periodicity    ;
  1591.    disk16bit             = history[i].pot16bit         ;
  1592.    release               = history[i].release         ;
  1593.    save_release          = history[i].save_release   ;
  1594.    display3d             = history[i].flag3d         ;
  1595.    Ambient               = history[i].ambient         ;
  1596.    RANDOMIZE             = history[i].randomize      ;
  1597.    haze                  = history[i].haze         ;
  1598.    transparent[0]        = history[i].transparent[0] ;
  1599.    transparent[1]        = history[i].transparent[1] ;
  1600.    rotate_lo             = history[i].rotate_lo      ;
  1601.    rotate_hi             = history[i].rotate_hi      ;
  1602.    distestwidth          = history[i].distestwidth   ;
  1603.    mxmaxfp               = history[i].mxmaxfp        ;
  1604.    mxminfp               = history[i].mxminfp        ;
  1605.    mymaxfp               = history[i].mymaxfp        ;
  1606.    myminfp               = history[i].myminfp        ;
  1607.    zdots                 = history[i].zdots          ;        
  1608.    originfp              = history[i].originfp       ;
  1609.    depthfp               = history[i].depthfp        ;    
  1610.    heightfp              = history[i].heightfp       ;
  1611.    widthfp               = history[i].widthfp        ;    
  1612.    distfp                = history[i].distfp         ;    
  1613.    eyesfp                = history[i].eyesfp         ;    
  1614.    neworbittype          = history[i].orbittype      ;
  1615.    juli3Dmode            = history[i].juli3Dmode     ;
  1616.    maxfn                 = history[i].maxfn          ;
  1617.    major_method          = (enum Major)history[i].major_method   ;
  1618.    minor_method          = (enum Minor)history[i].minor_method   ;
  1619.    bailout               = history[i].bailout        ;
  1620.    bailoutest            = (enum bailouts)history[i].bailoutest     ;
  1621.    maxit                 = history[i].iterations     ;
  1622.    old_demm_colors       = history[i].old_demm_colors;
  1623.    curfractalspecific    = &fractalspecific[fractype];
  1624.    potflag               = (potparam[0] != 0.0);
  1625.    if (inversion[0] != 0.0)
  1626.       invert = 3;
  1627.    usr_floatflag = (char)((curfractalspecific->isinteger) ? 0 : 1);
  1628.    far_memcpy(dacbox,history[i].dac,256*3);
  1629.    far_memcpy(olddacbox,history[i].dac,256*3);
  1630.    if(mapdacbox)
  1631.       far_memcpy(mapdacbox,history[i].dac,256*3);
  1632.    spindac(0,1);
  1633.    if(fractype == JULIBROT || fractype == JULIBROTFP)
  1634.       savedac = 0;
  1635.    else
  1636.       savedac = 1;
  1637.    switch(fractype)
  1638.    {
  1639.    case FORMULA:
  1640.    case FFORMULA:
  1641.       far_strncpy(FormFileName,history[i].filename,80);
  1642.       far_strncpy(FormName,    history[i].itemname,ITEMNAMELEN+1);
  1643.       break;
  1644.    case IFS:
  1645.    case IFS3D:
  1646.       far_strncpy(IFSFileName,history[i].filename,80);
  1647.       far_strncpy(IFSName    ,history[i].itemname,ITEMNAMELEN+1);
  1648.       break;
  1649.    case LSYSTEM:
  1650.       far_strncpy(LFileName,history[i].filename,80);
  1651.       far_strncpy(LName    ,history[i].itemname,ITEMNAMELEN+1);
  1652.       break;
  1653.    default:
  1654.       break;
  1655.    }
  1656. }
  1657.  
  1658. void checkfreemem(int secondpass)
  1659. {
  1660.    int oldmaxhistory;
  1661.    char far *tmp;
  1662.    static FCODE msg[] = 
  1663.       {" I'm sorry, but you don't have enough free memory \n to run this program.\n\n"};
  1664.    static FCODE msg2[] = {"To save memory, reduced maxhistory to "}; 
  1665.    tmp = farmemalloc(4096L);
  1666.    oldmaxhistory = maxhistory;
  1667.    if(secondpass && !history)
  1668.    {
  1669.       while(maxhistory >= 0) /* decrease history if necessary */
  1670.       {
  1671.          history = (HISTORY far *) 
  1672.             farmemalloc(((unsigned long)maxhistory * sizeof(HISTORY)));
  1673.          if(history)
  1674.             break;
  1675.          maxhistory--;   
  1676.       }
  1677.    }   
  1678.    if(extraseg == 0 || tmp == NULL)
  1679.    {    
  1680.       buzzer(2);
  1681. #ifndef XFRACT
  1682.       printf("%Fs",(char far *)msg);
  1683. #else
  1684.       printf("%s",msg);
  1685. #endif            
  1686.       exit(1);
  1687.    }
  1688.    farmemfree(tmp); /* was just to check for min space */
  1689.    if(secondpass && maxhistory < oldmaxhistory)
  1690.    {
  1691. #ifndef XFRACT
  1692.       printf("%Fs%d\n%Fs\n",(char far *)msg2,maxhistory,s_pressanykeytocontinue);
  1693. #else
  1694.       printf("%s%d\n%s\n",(char far *)msg2,maxhistory,s_pressanykeytocontinue);
  1695. #endif            
  1696.       getakey(); 
  1697.    }
  1698. }
  1699.